package com.youlu.campus.service.platform.impl;

import com.alibaba.fastjson.JSON;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.entity.PlatformUserComplaint;
import com.youlu.campus.entity.PlatformUserComplaintConsultRecord;
import com.youlu.campus.entity.VO.req.PlatformUserComplaintQueryVO;
import com.youlu.campus.service.platform.PlatformUserComplaintService;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@Service
public class PlatformUserComplaintServiceImpl implements PlatformUserComplaintService {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public boolean create(PlatformUserComplaint req) {
        req.setId(null);
        req.setCreatedTime(new Date());
        req = mongoTemplate.insert(req);
        if (StringUtils.isBlank(req.getId())) {
            return false;
        }
        return true;
    }

    @Override
    public Page<PlatformUserComplaint> list(PlatformUserComplaintQueryVO req) {
        Query query = new Query();
        if (StringUtils.isNotBlank(req.getMobile())) {
            query.addCriteria(Criteria.where("mobile").is(req.getMobile()));
        }
        if (StringUtils.isNotBlank(req.getUserId())) {
            query.addCriteria(Criteria.where("userId").is(req.getUserId()));
        }
        if (StringUtils.isNotBlank(req.getPlatform())) {
            query.addCriteria(Criteria.where("platform").is(req.getPlatform()));
        }
        if (StringUtils.isNotBlank(req.getActivityId())) {
            query.addCriteria(Criteria.where("activityId").is(req.getActivityId()));
        }
        if (StringUtils.isNotBlank(req.getFrom())) {
            query.addCriteria(Criteria.where("from").is(req.getFrom()));
        }
        if (StringUtils.isNotBlank(req.getStatus())) {
            if ("todo".equals(req.getStatus())) {
                Criteria criteria = new Criteria();
                criteria.orOperator(Criteria.where("status").is(null),
                        Criteria.where("status").is(req.getStatus()));
                query.addCriteria(criteria);
            } else {
                query.addCriteria(Criteria.where("status").is(req.getStatus()));
            }
        }
        if (Objects.nonNull(req.getVisitorHasMsg())) {
            if (Boolean.TRUE.equals(req.getVisitorHasMsg())) {
                query.addCriteria(Criteria.where("visitorHasMsg").is(req.getVisitorHasMsg()));
            } else {
                query.addCriteria(Criteria.where("visitorHasMsg").ne(Boolean.TRUE));
            }
        }
        if (req.getStartTime() != null || req.getEndTime() != null) {
            Criteria c=new Criteria();
            c = Criteria.where("createdTime");
            if (req.getStartTime() != null) {
                c.gte(req.getStartTime());
            }
            if (req.getEndTime() != null) {
                c.lte(req.getEndTime());
            }
            query.addCriteria(c);
        }
        query.addCriteria(Criteria.where("deleted").ne(Boolean.TRUE));
        Long count = mongoTemplate.count(query, PlatformUserComplaint.class);
        log.info(":>>> 平台的数量:{}，查询条件:{}", count, JSON.toJSON(query));
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<PlatformUserComplaint> orderPOS = mongoTemplate.find(query.with(pageRequest), PlatformUserComplaint.class);
        if (CollectionUtils.isNotEmpty(orderPOS)) {
            List<String> ids = new ArrayList<>();
            for (PlatformUserComplaint p : orderPOS) {
                ids.add(p.getId());
            }
            Query query1 = new Query();
            query1.addCriteria(Criteria.where("platformUserComplaintId").in(ids).and("readedStatus").ne(Boolean.TRUE).and("createType").is(req.getCreateType()));
            List<PlatformUserComplaintConsultRecord> records = mongoTemplate.find(query1, PlatformUserComplaintConsultRecord.class);
            for (PlatformUserComplaint p : orderPOS) {
                Long pCount = 0L;
                for (PlatformUserComplaintConsultRecord r : records) {
                    if (p.getId().equals(r.getPlatformUserComplaintId())) {
                        pCount++;
                    }
                }
                p.setUnReadMsgCount(pCount);
            }
        }
        return PageableExecutionUtils.getPage(orderPOS, pageRequest, () -> count);
    }

    @Override
    public PlatformUserComplaint findOne(String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        return mongoTemplate.findOne(query, PlatformUserComplaint.class);
    }

    @Override
    public boolean update(PlatformUserComplaint req) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(req.getId()));
        Update update = new Update();
        boolean toUpdate = false;
        if (StringUtils.isNotBlank(req.getStatus())) {
            update.set("status", req.getStatus());
            toUpdate = true;
        }
        if (Objects.nonNull(req.getVisitorHasMsg())) {
            update.set("visitorHasMsg", req.getVisitorHasMsg());
            toUpdate = true;
        }
        if (Objects.nonNull(req.getPlatformHasMsg())) {
            update.set("platformHasMsg", req.getPlatformHasMsg());
            toUpdate = true;
        }
        if (toUpdate) {
            update.set("updatedTime", new Date());
        }
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, PlatformUserComplaint.class);
        return updateResult.getModifiedCount() > 0 ? true : false;
    }

    @Override
    public Long unReadMsgCount(String userId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        List<PlatformUserComplaint> pcs = mongoTemplate.find(query, PlatformUserComplaint.class);
        if (Objects.isNull(pcs) || CollectionUtils.isEmpty(pcs)) {
            return 0L;
        }
        List<String> pcsIds = new ArrayList<>();
        for (PlatformUserComplaint pc : pcs) {
            pcsIds.add(pc.getId());
        }
        Query query1 = new Query();
        query1.addCriteria(Criteria.where("platformUserComplaintId").in(pcsIds));
        query1.addCriteria(Criteria.where("readedStatus").ne(Boolean.TRUE));
        query1.addCriteria(Criteria.where("createType").is("system"));
        return mongoTemplate.count(query1, PlatformUserComplaintConsultRecord.class);
    }

    @Override
    public HashMap<String, Long> statistics(String createType) {
        HashMap<String, Long> res = new HashMap<>();
        Query query = new Query();
        query.addCriteria(Criteria.where("status").ne("done"));
        query.addCriteria(Criteria.where("deleted").ne(Boolean.TRUE));
        List<PlatformUserComplaint> pucs = mongoTemplate.find(query, PlatformUserComplaint.class);
        if (Objects.isNull(pucs) || CollectionUtils.isEmpty(pucs)) {
            res.put("doingCount", 0L);
            res.put("todoCount", 0L);
            res.put("unReadCount", 0L);
            return res;
        }
        List<String> pucIds = new ArrayList<>();
        Long doingCount = 0L;
        Long todoCount = 0L;
        for (PlatformUserComplaint puc : pucs) {
            if (Objects.isNull(puc.getStatus()) || "todo".equals(puc.getStatus())) {
                todoCount++;
            } else if ("doing".equals(puc.getStatus())) {
                doingCount++;
            }
            pucIds.add(puc.getId());
        }
        res.put("doingCount", doingCount);
        res.put("todoCount", todoCount);
        Query query1 = new Query();
        query1.addCriteria(Criteria.where("platformUserComplaintId").in(pucIds));
        query1.addCriteria(Criteria.where("readedStatus").ne(Boolean.TRUE));
        query1.addCriteria(Criteria.where("createType").is(createType));
        Long count = mongoTemplate.count(query1, PlatformUserComplaintConsultRecord.class);
        res.put("unReadCount", count);
        return res;
    }

    @Override
    public boolean delete(String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        Update update = new Update();
        update.set("deleted", Boolean.TRUE);
        update.set("updatedTime", new Date());
        UpdateResult result = mongoTemplate.updateFirst(query, update, PlatformUserComplaint.class);
        return result.getModifiedCount() > 0 ? true : false;
    }
}
